/*
 * KBestTreebank.cpp
 *
 *  Created on: Dec 18, 2014
 *      Author: Phong
 */

#include "KBestTreebank.h"
#include "Utils.h"
#include "Depstruct.h"


KBestTreebank::~KBestTreebank() {
    for (int i = 0; i < trees.size(); i++) {
        for (int j = 0; j < trees[i].size(); j++)
            Deptree::free(trees[i][j]);
    }
}

KBestTreebank* KBestTreebank::share() {
    refCount++;
    return this;
}

void KBestTreebank::free(KBestTreebank* tb) {
    tb->refCount--;
    if (tb->refCount == 0) delete tb;
}

KBestTreebank* KBestTreebank::load(string path, Treebank* tb, Dictionary* vocaDic,
		Dictionary* posDic, Dictionary* deprelDic) {
	return load(path, tb, vocaDic, posDic, deprelDic, nTop);
}

KBestTreebank* KBestTreebank::load(string path, Treebank* tb, Dictionary* vocaDic, Dictionary* posDic,
		Dictionary* deprelDic, int nTop) {
	KBestTreebank* kbestTb = new KBestTreebank();
	cout << "load " << path << endl;

	// read dsbank
	vector<Depstruct*> dsbank;
	fstream reader(path, ios::in);
	vector<string> rows;
	string line;

	while (getline(reader, line)) {
		vector<string> comps = Utils::splitStringWoRegex(line, "\t");
		if (comps.size() == 1) {
            Depstruct* ds = Depstruct::create(rows, vocaDic, posDic, deprelDic);
            dsbank.push_back(ds);
            rows.clear();

			if (dsbank.size() % 1000 == 0) {
                cout << dsbank.size() << "\r" << flush;
			}

		}
		else {
			rows.push_back(line);
		}
	}
    cout << dsbank.size() << endl;
	reader.close();

	// grouping
	reader.open(path + "." + kbestScoreSuffix, ios::in);
	int tid = -1;
	int c = -1;

	while (getline(reader, line)) {
		c++;

		vector<string> comps = Utils::splitString(line, "[ \t]");
		vector<real> s;
		vector<Deptree*> t;

		for (int i = 0; i < comps.size(); i++) {
			if (i < nTop) {
				s.push_back((real)stod(comps[i]));
				Depstruct* ds = dsbank[++tid];
				ds->tokens = tb->storage[c]->ds->tokens;
				Deptree* tree = ds->toDepTree();
				Depstruct::free(ds);
				t.push_back(tree);
			}
			else tid++;
		}
		kbestTb->trees.push_back(t);
		kbestTb->scores.push_back(s);
	}
	reader.close();

	return kbestTb;
}
